<template>
  <ele-page
    flex-table
    :multi-card="false"
    hide-footer
    style="min-height: 420px"
  >
    <ele-card
      flex-table
      :body-style="{ padding: '0 0 0 16px', overflow: 'hidden' }"
    >
      <ele-split-panel
        ref="splitRef"
        flex-table
        size="256px"
        allow-collapse
        :custom-style="{ borderWidth: '0 1px 0 0', padding: '5px 0' }"
        :body-style="{ padding: '16px 16px 16px 0', overflow: 'hidden' }"
        :style="{ height: '100%', overflow: 'visible' }"
      >
        <div style="padding: 0 16px 12px 0">
          <el-input
            v-model="keywords"
            clearable
            :maxlength="20"
            placeholder="输入字典名称搜索"
            :prefix-icon="Search"
          />
        </div>
        <div style="margin-bottom: 12px">
          <el-button
            type="primary"
            class="ele-btn-icon"
            :icon="Plus"
            @click="openEdit()"
          >
            新增
          </el-button>
          <el-button
            type="warning"
            :disabled="!current"
            class="ele-btn-icon"
            :icon="EditPen"
            @click="openEdit(current)"
          >
            编辑
          </el-button>
          <el-button
            type="danger"
            :disabled="!current"
            class="ele-btn-icon"
            :icon="Delete"
            @click="remove"
          >
            删除
          </el-button>
        </div>
        <ele-loading :loading="loading" class="dict-tree">
          <el-tree
            ref="treeRef"
            :data="data"
            highlight-current
            node-key="id"
            :props="{ label: 'name' }"
            :expand-on-click-node="false"
            :default-expand-all="true"
            :filter-node-method="filterNode"
            @node-click="onNodeClick"
          >
            <template #default="{ data: d }">
              <div>{{ d.name }}</div>
              <div style="font-size: 12px; opacity: 0.8; font-weight: normal">
                &nbsp;({{ d.code }})
              </div>
            </template>
          </el-tree>
        </ele-loading>
        <template #body>
          <DictDataList
            v-if="current && current.id"
            :dict-id="current.id"
          />
        </template>
      </ele-split-panel>
    </ele-card>
    <DictEdit v-model="showEdit" :data="editData" @done="query" />
  </ele-page>
</template>

<script setup>
import { listDict, removeDict } from '@/api/system/dict'
import { useMobile } from '@/utils/use-mobile'
import { Delete, EditPen, Plus, Search } from '@element-plus/icons-vue'
import { EleMessage } from 'ele-admin-plus/es'
import { ElMessageBox } from 'element-plus/es'
import { nextTick, ref, watch } from 'vue'
import DictDataList from './components/dict-data-list.vue'
import DictEdit from './components/dict-edit.vue'

defineOptions({
  name: 'SystemDict',
})

/** 是否是移动端 */
const { mobile } = useMobile()

/** 分割面板组件 */
const splitRef = ref(null)

/** 树组件 */
const treeRef = ref(null)

/** 加载状态 */
const loading = ref(true)

/** 树形数据 */
const data = ref([])

/** 选中数据 */
const current = ref(null)

/** 机构搜索关键字 */
const keywords = ref('')

/** 是否显示编辑弹窗 */
const showEdit = ref(false)

/** 编辑回显数据 */
const editData = ref(null)

/** 查询 */
function query() {
  loading.value = true
  listDict()
    .then((res) => {
      data.value = res.data ?? []
      nextTick(() => {
        onNodeClick(data.value[0])
      })
    })
    .finally(() => {
      loading.value = false
    })
}

/** 选择数据 */
function onNodeClick(row) {
  // 移动端自动收起左侧
  if (current.value != null && mobile.value)
    splitRef.value?.toggleCollapse?.(true)

  if (row && row.id) {
    current.value = row
    treeRef.value?.setCurrentKey?.(row.id)
  }
  else {
    current.value = null
  }
}

/** 打开编辑弹窗 */
function openEdit(row) {
  editData.value = row ?? null
  showEdit.value = true
}

/** 删除 */
function remove() {
  const row = current.value
  if (!row)
    return

  ElMessageBox.confirm(`确定要删除“${row.name}”吗?`, '系统提示', {
    type: 'warning',
    draggable: true,
  })
    .then(() => {
      const loading = EleMessage.loading('请求中..')
      removeDict(row.id)
        .then((msg) => {
          loading.close()
          EleMessage.success(msg)
          query()
        })
        .catch((e) => {
          loading.close()
          EleMessage.error(e.message)
        })
    })
    .catch(() => {})
}

/** 树过滤方法 */
function filterNode(value, data) {
  if (value)
    return !!(data.name && data.name.includes(value))

  return true
}

/** 树过滤 */
watch(keywords, (value) => {
  treeRef.value?.filter?.(value)
})

query()
</script>

<style lang="scss" scoped>
  .dict-tree {
    flex: 1;
    padding-right: 16px;
    overflow: auto;

    :deep(.el-tree-node__content) {
      height: 36px;
      line-height: 36px;
      border-radius: calc((var(--el-border-radius-small) - 2px) * 3);
      transition: all 0.2s;

      & > .el-tree-node__expand-icon {
        padding: 2px;
      }
    }

    :deep(.el-tree-node.is-current > .el-tree-node__content) {
      color: var(--el-color-primary);
      font-weight: bold;
    }
  }
</style>
